#include "trackwaypoint.h"
#include "configwidget.h"

#define WAYPOINT_OFFSET_X -8
#define WAYPOINT_OFFSET_Y -43

int waypoint_common_id = 0;

extern ConfigWidget* conf;
TrackWaypoint::TrackWaypoint(const TrackPoint& other, const QString& n, const QString& d, int& wid) :
    TrackPoint(other)
{
    wid = id = waypoint_common_id++;
    name = n;
    description = d;
    timestamp = QDateTime::currentDateTime();
}

TrackWaypoint::TrackWaypoint(const TrackPoint& other, const QString& n, const QString& d ) :
    TrackPoint(other)
{
    id = waypoint_common_id++;
    name = n;
    description = d;
    timestamp = QDateTime::currentDateTime();
}

TrackWaypoint::TrackWaypoint(QXmlStreamReader* stream) :
    TrackPoint()
{
    id = waypoint_common_id++;
    fromGpx( stream );
}

TrackWaypoint::TrackWaypoint() :
   TrackPoint()
{
    name = description = "";
    id = waypoint_common_id++;
}
int TrackWaypoint::getId()
{
    return id;
}

void TrackWaypoint::fromGpx(QXmlStreamReader *stream)
{
    QXmlStreamAttributes attributes = stream->attributes();
    double lat = attributes.value("lat").toString().toDouble();
    double lon = attributes.value("lon").toString().toDouble();
    double ele,spd;
    QString time;

    stream->readNext();

    while ( !(stream->isEndElement() &&
            stream->name() == "wpt") )
    {
        if ( stream->isStartElement() )
        {
            if ( stream->name() == "ele")
            {
                 stream->readNext();
                 ele = stream->text().toString().toDouble();
            }
            else if ( stream->name() == "time")
            {
                 stream->readNext();
                 time = stream->text().toString();
            }
            else if ( stream->name() == "speed")
            {
                 stream->readNext();
                 spd = stream->text().toString().toDouble();
            }
            else if ( stream->name() == "hdop")
            {
                 stream->readNext();
                 precision = stream->text().toString().toDouble();
                 if ( precision < 1.0 )
                     precision = 1.0;
            }
            else if ( stream->name() == "time")
            {
                 stream->readNext();
                 timestamp = QDateTime::fromString( stream->text().toString(),"yyyy'-'MM'-'dd'T'hh':'mm':'ss'Z'" );
            }
            else if ( stream->name() == "name")
            {
                 stream->readNext();
                 name = stream->text().toString();
            }
            else if ( stream->name() == "desc")
            {
                 stream->readNext();
                 description = stream->text().toString();
            }
        }
        stream->readNext();
    }
    position = QPointF( lon, lat );
    altitude = ele;
    speed = spd;
    timestamp = QDateTime::fromString( time,"yyyy'-'MM'-'dd'T'hh':'mm':'ss'Z'" );
}

// Set point name (used for waypoints)
bool TrackWaypoint::setName( const QString& n)
{
    if ( n == name )
        return false;
    name = n;
    return true;
}

QString TrackWaypoint::getName()
{
    return name;
}

// Set point description (used for waypoints)
bool TrackWaypoint::setDescription( const QString& d )
{
    if ( d == description )
        return false;
    description = d;
    return true;
}

QString TrackWaypoint::getDescription()
{
    return description;
}

void TrackWaypoint::toGpx(QXmlStreamWriter* stream) const
{
    QPointF point = position;
    QString lat = QString("%1").arg(point.y(), 0, 'f', 7);
    QString lon = QString("%1").arg(point.x(),0,'f',7);
    QString alt = QString("%1").arg(altitude,0,'f',7);
    QString pre = QString("%1").arg(precision, 0, 'f', 2);
    QString spd = QString("%1").arg(speed, 0, 'f', 2);

    stream->writeStartElement("wpt");
    stream->writeAttribute("lat", lat);
    stream->writeAttribute("lon", lon);
    stream->writeTextElement("name", name);
    stream->writeTextElement("desc", description);
    stream->writeTextElement("ele", alt);
    stream->writeTextElement("speed", spd);
    stream->writeTextElement("time", timestamp.toString("yyyy-MM-ddThh:mm:ssZ"));    
    stream->writeTextElement("hdop", pre);
    stream->writeEndElement();
}

QPoint TrackWaypoint::draw(QPainter & painter, QColor color, const QTransform& matrix) const
{
    // TODO: optimize this by caching values to save one function call
    bool drawIcon = conf->getDrawWaypointIcon();
    bool drawName = conf->getDrawWaypointName();

    painter.save();
    painter.setPen( QPen( QBrush(color), 0) );

    QPoint screenPt = (position * matrix).toPoint();

    // First draw the circle to match the waypoint
    painter.drawRect( screenPt.x()-2, screenPt.y()-2, 4, 4 );
    // TODO: enquiry and check this bug: hang forever on symbian then pt = QPoint(273667,-1621784)
//    painter.drawEllipse( screenPt, 3,3 );

    if ( drawIcon || drawName )
    {
        if ( drawIcon )
        {
            QPixmap pxm( ":/icons/waypoint_to.png" );
            painter.drawPixmap( screenPt - QPoint( pxm.width(), pxm.height() ), pxm );
        }
        if ( drawName )
            painter.drawText( screenPt + QPoint( 5, 5), name );
    }
    painter.restore();
    return screenPt;
}
